<!--
author:        yangmingchao <amustlang_yang@foxmail.com>
date:          2024-01-10 21:56:27
component:     list
Copyright © YourCompanyName All rights reserved
-->

<template>
    <div class="app-container">
        <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
            <el-form-item label="文件名" prop="fileName">
                <el-input v-model="queryParams.fileName" placeholder="请输入文件名" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="附件分类" prop="type">
                <el-select v-model="queryParams.type" filterable allow-create laceholder="Select">
                    <el-option v-for="item in file_tpe_dict" :key="item.value" :label="item.label"
                        :value="item.value" />
                </el-select>
            </el-form-item>
            <el-form-item label="文件大小" prop="fileSize">
                <el-input v-model="queryParams.fileSize" placeholder="请输入文件大小" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="后缀" prop="suffix">
                <el-input v-model="queryParams.suffix" placeholder="请输入后缀" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="存储引擎" prop="engine">
                <el-input v-model="queryParams.engine" placeholder="请输入存储引擎" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="文件宽度" prop="fileWidth">
                <el-input v-model="queryParams.fileWidth" placeholder="请输入文件宽度" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="文件高度" prop="fileHeight">
                <el-input v-model="queryParams.fileHeight" placeholder="请输入文件高度" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item>
                <el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
                <el-button icon="refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
            <el-col :span="1.5">
                <el-button type="primary" plain icon="plus" @click="handleAdd"
                    v-hasPermi="['system:file:add']">新增</el-button>
            </el-col>
            <el-col :span="1.5">
                <el-button type="success" plain icon="edit" :disabled="single" @click="handleUpdate"
                    v-hasPermi="['system:file:edit']">修改</el-button>
            </el-col>
            <el-col :span="1.5">
                <el-button type="danger" plain icon="delete" :disabled="multiple" @click="handleDelete"
                    v-hasPermi="['system:file:remove']">删除</el-button>
            </el-col>
            <el-col :span="1.5">
                <el-button type="warning" plain icon="download" @click="handleExport"
                    v-hasPermi="['system:file:export']">导出</el-button>
            </el-col>
            <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>

        <el-table v-loading="loading" :data="fileList" @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="ID" align="center" prop="id">
                <template #default="scope">
                    <el-tooltip effect="dark" :content="scope.row.id" placement="bottom">
                        <div class="fileName-content">{{ scope.row.id }}</div>
                    </el-tooltip>
                </template>
            </el-table-column>
            <el-table-column label="预览" align="center" prop="type">
                <template #default="scope">
                    <BppendixPreview :id="scope.row.id" :displayMode="scope.row.type == '图片' ? 2 : 1" :width="60"
                        :height="68" />
                </template>
            </el-table-column>
            <el-table-column label="类别" align="center" prop="type" />
            <el-table-column label="文件名" align="center" prop="fileName">
                <template #default="scope">
                    <el-tooltip effect="dark" :content="scope.row.fileName" placement="bottom">
                        <div class="fileName-content">{{ scope.row.fileName }}</div>
                    </el-tooltip>
                </template>
            </el-table-column>
            <el-table-column label="文件大小" align="center" prop="fileSize" />
            <el-table-column label="媒体类型" align="center" prop="mimeType" />
            <el-table-column label="后缀" align="center" prop="suffix" />
            <el-table-column label="存储引擎" align="center" prop="engine" />
            <el-table-column label="文件宽度" align="center" prop="fileWidth" />
            <el-table-column label="文件高度" align="center" prop="fileHeight" />
            <el-table-column label="操作" align="center" width="210" class-name="small-padding fixed-width">
                <template #default="scope">
                    <!-- <el-button link icon="edit" @click="handleUpdate(scope.row)"
                        v-hasPermi="['system:file:edit']">修改</el-button> -->
                    <el-button type="danger" link icon="delete" @click="handleDelete(scope.row)"
                        v-hasPermi="['system:file:remove']">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
            v-model:limit="queryParams.pageSize" @pagination="getList" />
        <!-- 添加或修改文件对话框 -->
        <el-dialog :title="title" v-model="open" width="600px" append-to-body>
            <el-form ref="form" :model="form" :rules="rules" label-width="80px">
                <!-- <el-form-item label="附件" prop="file">
                    <el-upload :auto-upload="false" :show-file-list="false" multiple :on-change="beforeAvatarUpload">
                        <el-input v-model="form.fileName" placeholder="请选择文件" />
                    </el-upload>
                </el-form-item> -->
                <el-form-item label="附件分类" prop="type">
                    <el-select v-model="form.type" filterable allow-create laceholder="Select">
                        <el-option v-for="item in file_tpe_dict" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitForm">上 传</el-button>
                    <el-button @click="cancel">取 消</el-button>
                </div>
            </template>
        </el-dialog>
        <el-dialog title="上传" v-model="batchOpen" width="80%" append-to-body class="dialogclass"
            :close-on-click-modal="false" :close-on-press-escape="false">
            <el-col :span="24" style="margin: 10px 0;">
                <el-upload :auto-upload="false" :show-file-list="false" multiple :on-change="beforeAvatarUpload">
                    <el-button>批量上传</el-button>
                </el-upload>
                支持图片格式：{{ imageType }}
                支持视频格式：{{ vedioType }}
            </el-col>
            <el-col :span="24">
                <el-table :data="batchUpload" style="width: 100%">
                    <el-table-column label="UID" prop="uid"></el-table-column>
                    <el-table-column label="文件名" prop="name"></el-table-column>
                    <el-table-column label="文件大小" prop="size">
                        <template #default="props">
                            {{ renderSize(props.row.size) }}
                        </template>
                    </el-table-column>
                    <el-table-column label="文件类型" prop="filetype">
                        <template #default="props">
                            {{ fileExtension(props.row.name) }}
                            <div style="font-size: 12px;color: red;">{{ whetherToSupport(props.row) ? '' : '该格式不支持上传' }}
                            </div>
                        </template>
                    </el-table-column>
                    <el-table-column label="文件分类" prop="type">
                        <template #default="props">
                            <el-select v-model="props.row.type" filterable allow-create laceholder="Select">
                                <el-option v-for="item in file_tpe_dict" :key="item.value" :label="item.label"
                                    :value="item.value" />
                            </el-select>
                        </template>
                    </el-table-column>
                    <el-table-column label="状态" prop="date">
                        <template #default="props">
                            <el-tag v-if="props.row.uploadStatus == 1">待上传</el-tag>
                            <el-tag v-if="props.row.uploadStatus == 2" type="success">上传成功</el-tag>
                            <el-tag v-if="props.row.uploadStatus == 3" type="danger">上传失败</el-tag>
                            <el-progress v-if="props.row.uploadStatus != 2 && props.row.uploadStatus != 3"
                                :percentage="props.row.loadingText" />
                        </template>
                    </el-table-column>
                </el-table>
            </el-col>
            <template #footer>
                <div class="dialog-footer">
                    <span style="font-size: 12px;margin-right: 10px;"><span style="color: #f40;">*
                        </span>提交时，只上传列表中【待上传】、【失败】状态的数据，不会产生重复提交，请放心大胆的操作!!</span>
                    <el-button type="primary" v-loading="batchUploadLoading" v-if="!isAllUploadSuccess"
                        @click="batchSubmitForm">提 交</el-button>
                    <el-button @click="batchOpen = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script>
import { listFile, getFile, delFile, addFile, updateFile, fileTypes, putObject, ossAddFile } from "@/api/skit/resource";
import { isSuccess, transformDict } from '@/utils/pageUtils'
import { isImageType } from '@/utils/pageUtils'
import ossApi from '@/utils/ossRequest'

export default {
    name: "Resource",
    props: {
        // 是否显示搜索框
        showSearchProps: {
            type: Boolean,
            default: true,
        },
        // 默认查询类型
        type: {
            type: String,
            default: '',
        }
    },
    data() {
        return {
            ...this.useDict('file_tpe_dict'),
            // 遮罩层
            loading: true,
            // 选中数组
            ids: [],
            // 非单个禁用
            single: true,
            // 非多个禁用
            multiple: true,
            // 显示搜索条件
            showSearch: false,
            // 总条数
            total: 0,
            // 文件表格数据
            fileList: [],
            // 弹出层标题
            title: "",
            // 是否显示弹出层
            open: false,
            // 新增弹窗
            batchOpen: false,
            // 查询参数
            queryParams: {
                pageNum: 1,
                pageSize: 10,
                type: null,
                fileName: null,
                fileSize: null,
                mimeType: null,
                suffix: null,
                engine: null,
                fileWidth: null,
                fileHeight: null
            },
            // 表单参数
            form: {},
            // 批量上传
            batchUpload: [],
            // 表单校验
            rules: {
                file: [{ required: true, message: "请选择文件", trigger: "onchange" }],
                type: [{ required: true, message: "请选择类型", trigger: "blur" }],
            },
            // 文件类别
            fileTypesOptions: [],
            // 批量上传时按钮状态
            batchUploadLoading: false,
            // 选中原数据
            checkRows: null,
            // 常见的图片类型
            imageType: import.meta.env.VITE_IMAGE_TYPE,
            // 常见的视频类型
            vedioType: import.meta.env.VITE_VIDEO_TYPE,
        };
    },
    watch: {
        type(ov, lv) {
            console.log('BppendixSelect---watch--type', ov, lv);
        }
    },
    computed: {
        // 是否全部上传完成
        isAllUploadSuccess() {
            let tempFlag = true;
            if (this.batchUpload.length == 0) {
                return false;
            }
            this.batchUpload.map(item => {
                // 有待上传或者失败数据
                if ([1, 3].includes(item.uploadStatus)) {
                    tempFlag = false;
                }
            })
            return tempFlag;
        }
    },
    created() {

        // this.getfileTypes();
        this.showSearch = this.showSearchProps;
        this.queryParams.type = this.type;
        this.getList();
    },
    methods: {
        isImageType,
        // 获取文件后缀
        fileExtension(fileName) {
            return fileName.substring(fileName.lastIndexOf('.') + 1);
        },
        // 判断该文件类型是否支持
        whetherToSupport(row) {
            let isSuccess = true;
            const suffix = this.fileExtension(row.name).toLowerCase();
            if (row.type === '视频' && !this.vedioType.split(',').includes(suffix)) {
                isSuccess = false;
            } else if (row.type === '图片' && !this.imageType.split(',').includes(suffix)) {
                isSuccess = false;
            }
            return isSuccess;
        },
        // 获取文件类型
        getFileType(fileName) {
            let suffix = this.fileExtension(fileName).toLowerCase();
            // 常见的图片类型
            const imageType = import.meta.env.VITE_IMAGE_TYPE;
            // 常见的视频类型
            const vedioType = import.meta.env.VITE_VIDEO_TYPE;
            if (imageType.indexOf(suffix) != -1) {
                return '图片'
            } else if (vedioType.indexOf(suffix) != -1) {
                return '视频'
            } else {
                return '文件'
            }

        },
        // 格式化文件大小的JS方法
        renderSize(filesize) {
            if (null == filesize || filesize == '') {
                return "0 Bytes";
            }
            var unitArr = new Array("Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
            var index = 0;
            var srcsize = parseFloat(filesize);
            index = Math.floor(Math.log(srcsize) / Math.log(1024));
            var size = srcsize / Math.pow(1024, index);
            size = size.toFixed(2);//保留的小数位数
            return size + unitArr[index];
        },
        beforeAvatarUpload(file) {
            console.log('选中文件', file)
            this.batchUpload.push({
                ...file,
                type: this.getFileType(file.name),
                uploadStatus: 1,// 1待上传 2成功  3失败
            })
        },
        /** 查询文件列表 */
        getList() {
            this.loading = true;
            listFile(this.queryParams).then(response => {
                const list = response.rows && response.rows.length > 0 ? response.rows : [];
                this.fileList = list.map(item => {
                    item.fileName = decodeURIComponent(item.fileName)
                    return item;
                });
                this.total = response.total;
                this.loading = false;
            });
        },
        // 取消按钮
        cancel() {
            this.open = false;
            this.reset();
        },
        // 表单重置
        reset() {
            this.form = {
                id: null,
                file: null,
                type: null,
                fileName: null,
            };
            this.batchUpload = [];
            this.resetForm("form");
        },
        /** 搜索按钮操作 */
        handleQuery() {
            this.queryParams.pageNum = 1;
            this.getList();
        },
        /** 重置按钮操作 */
        resetQuery() {
            this.resetForm("queryForm");
            this.handleQuery();
        },
        // 多选框选中数据
        handleSelectionChange(selection) {
            this.ids = selection.map(item => item.id)
            this.checkRows = selection;
            this.single = selection.length !== 1
            this.multiple = !selection.length
        },
        /** 新增按钮操作 */
        handleAdd() {
            this.reset();
            // this.open = true;
            // this.title = "文件上传";
            this.batchOpen = true;
        },
        /** 修改按钮操作 */
        handleUpdate(row) {
            this.reset();
            const id = row.id || this.ids
            getFile(id).then(response => {
                this.form = response.data;
                this.open = true;
                this.title = "修改文件";
            });
        },
        // 提交之前校验文件格式
        batchSubmitFormAfter() {
            let isSuccess = true;
            for (let index = 0; index < this.batchUpload.length; index++) {
                const item = this.batchUpload[index];
                if (!this.whetherToSupport(item)) {
                    isSuccess = false;
                }
            }
            return isSuccess;
        },
        // 批量提交
        async batchSubmitForm() {
            if (!this.batchSubmitFormAfter()) {
                this.$modal.msgWarning("提交失败，请检查文件类型是否支持上传");
                return;
            }
            this.batchUploadLoading = true;
            for (let index = 0; index < this.batchUpload.length; index++) {
                const item = this.batchUpload[index];
                const fileName = encodeURIComponent(item.name);
                // 只上传【待上传】、【失败】的数据
                if (item.uploadStatus !== 2) {
                    // 重置上传状态为待上传
                    item.uploadStatus = 1;
                    // 获取oss配置
                    const currentForm = new FormData();
                    currentForm.append('key', fileName);
                    const respone = await putObject(currentForm);
                    console.log('putObject===respone', respone)
                    if (isSuccess(respone)) {
                        const { data, code } = respone;
                        console.log('process.env', process.env.NODE_ENV !== 'development')
                        // data.url = process.env.NODE_ENV == 'development' ? '/oss-api/' + data.ossKey : data.url;
                        data.data = item.raw;
                        // 添加上传进度事件监听
                        data.onUploadProgress = (progressEvent) => {
                            let num = progressEvent.loaded / progressEvent.total * 100 | 0 // 计算进度
                            item.loadingText = num
                        }
                        // 上传阿里云oss
                        const ossRespone = await ossApi(data)
                        console.log('oss返回信息', ossRespone)
                        if (ossRespone.status === 200) {
                            const formData = new FormData();
                            formData.append('key', data.ossKey);
                            formData.append('type', item.type || '');
                            formData.append('fileSizeBytes', item.size);
                            // 更新上传接口
                            const ossAddRespone = await ossAddFile(formData);
                            // 更新状态为成功或失败
                            isSuccess(ossAddRespone) ? (item.uploadStatus = 2) : (item.uploadStatus = 3);
                        }

                    }
                }
            }
            this.batchUploadLoading = false;
            this.getList();
        },
        /** 提交按钮 */
        submitForm() {
            this.$refs["form"].validate(valid => {
                if (valid) {
                    if (this.form.id != null) {
                        updateFile(this.form).then(response => {
                            this.$modal.msgSuccess("修改成功");
                            this.open = false;
                            this.getList();
                            // this.getfileTypes();
                        });
                    } else {
                        addFile(this.form).then(response => {
                            this.$modal.msgSuccess("新增成功");
                            this.open = false;
                            this.getList();
                            // this.getfileTypes();
                        });
                    }
                }
            });
        },
        /** 删除按钮操作 */
        handleDelete(row) {
            const ids = row.id || this.ids;
            this.$modal.confirm('是否确认删除文件编号为"' + ids + '"的数据项？').then(function () {
                return delFile(ids);
            }).then(() => {
                this.getList();
                this.$modal.msgSuccess("删除成功");
            }).catch(() => { });
        },
        /** 导出按钮操作 */
        handleExport() {
            this.download('drama/file/export', {
                ...this.queryParams
            }, `file_${new Date().getTime()}.xlsx`)
        },
        /**
         * 获取文件类型
         */
        // async getfileTypes() {
        // const respone = await fileTypes();
        // if (isSuccess(respone)) {
        //     this.fileTypesOptions = transformDict(respone.data);
        // }
        // }
    }
};
</script>
<style lang='scss'>
.dialogclass>.el-dialog__body {
    padding: 0 10px !important;
}

.fileName-content {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
}
</style>